import { defineStore } from "pinia";
import { getToken, removeToken, setToken } from "../utils/token-utils";
import type { UserInfoState } from "./interface";
import { staticRoutes, anyRoutes } from "@/router/routes";
import { loginApi, getUserInfoApi, getAsyncRoutesUrlApi } from "@/api/user";
import router from "@/router";

const modules = import.meta.glob(["../views/**/*.vue", "../layout/**/*.vue"]);

const addComponent = (asyncRoutes: any) => {
  return asyncRoutes.map((route: any) => {
    const componentPath = route.component.replace("@", "../");
    if (route.children && route.children.length) {
      route.children = addComponent(route.children);
    }
    return {
      ...route,
      // @layout/index.vue
      // ../layout/index.vue
      component: modules[componentPath],
    };
  });
};

const addRoutes = (routes: any) => {
  routes.forEach((route: any) => {
    router.addRoute(route);
  });
};

/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfoStore = defineStore("userInfo", {
  state: (): UserInfoState => ({
    token: getToken() as string,
    name: "",
    avatar: "",
    menuRoutes: [], // 路由配置项（将来会渲染成左侧菜单）
    routes: [], // 路由权限列表
    buttons: [], // 按钮权限列表
  }),

  actions: {
    async login(username: string, password: string) {
      const res = await loginApi(username, password);
      this.token = res.token; // 存在pinia
      setToken(res.token); // 存在localStorage
    },

    async getInfo() {
      // 发送请求获取用户数据
      // 得到：1. 用户数据 2. 动态路由表 3. 按钮权限表
      const [userInfo, asyncRoutes] = await Promise.allSettled([
        getUserInfoApi(),
        getAsyncRoutesUrlApi(),
      ]);

      if (userInfo.status === "fulfilled") {
        // 1. 用户数据
        this.name = userInfo.value.name;
        this.avatar = userInfo.value.avatar;
        // 3. 按钮权限表
        this.buttons = userInfo.value.buttons;
      }

      if (asyncRoutes.status === "fulfilled") {
        // 2. 动态路由表
        // - 将动态路由表追加到路由中让其生效 router.addRoute
        const routes = addComponent(asyncRoutes.value);
        // 需要将请求回来的路由表中的组件 转化为 真正的组件
        addRoutes([...routes, ...anyRoutes]);
        // - 将动态路由表更新成routes，因为左侧菜单会根据routes来生成菜单
        this.menuRoutes = [...staticRoutes, ...routes];
      }
    },

    reset() {
      // 删除localStorage中保存的token
      removeToken();
      // 提交重置用户信息的mutation
      this.token = "";
      this.routes = [];
      this.buttons = [];
      this.name = "";
      this.avatar = "";
    },
  },
});
